package org.springblade.core.license;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import de.schlichtherle.license.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Optional;
import java.util.prefs.Preferences;

/**
 * License校验类
 *
 * @author zifangsky
 * @date 2018/4/20
 * @since 1.0.0
 */
public class LicenseVerify {
	private static Logger logger = LogManager.getLogger(LicenseVerify.class);


	/**
	 * 安装License证书
	 *
	 * @author zifangsky
	 * @date 2018/4/20 16:26
	 * @since 1.0.0
	 */
	public synchronized LicenseContent install(LicenseVerifyParam param) {
		LicenseContent result = null;
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//1. 安装证书
		try {
			LicenseManager licenseManager = LicenseManagerHolder.getInstance(initLicenseParam(param));
			licenseManager.uninstall();
			result = licenseManager.install(getLicenseFile(param.getLicensePath()));
			logger.info(MessageFormat.format("vc success,valid：{0} - {1}", format.format(result.getNotBefore()), format.format(result.getNotAfter())));
		} catch (Exception e) {
			logger.error("vc error！", e);
		}
		return result;
	}

	private File getLicenseFile(String filePath) {
		if (StringUtils.startsWith(filePath, "classpath")) {
			File file = new File("/tmp/license.lic");
			if (file.exists()) {
				FileUtil.del(file);
			}
			String path = filePath.substring("classpath:".length());
			ClassPathResource resource = new ClassPathResource(path);
			FileUtil.writeFromStream(resource.getStream(), file);
			return file;
		} else {
			return new File(filePath);
		}
	}

	/**
	 * 校验License证书
	 *
	 * @return boolean
	 * @author zifangsky
	 * @date 2018/4/20 16:26
	 * @since 1.0.0
	 */
	public boolean verify() {
		LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		//2. 校验证书
		try {
			LicenseContent licenseContent = licenseManager.verify();

			logger.info(MessageFormat.format("版本校验通过，版本有效期：{0} - {1}", format.format(licenseContent.getNotBefore()), format.format(licenseContent.getNotAfter())));
			return true;
		} catch (Exception e) {
			logger.error("版本校验失败！", e);
			return false;
		}
	}

	public static Optional<LicenseContent> getLicenseContent() {
		LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
		try {
			LicenseContent licenseContent = licenseManager.verify();
			return Optional.ofNullable(licenseContent);
		} catch (Exception e) {
			return Optional.empty();
		}
	}

	/**
	 * 初始化证书生成参数
	 *
	 * @param param License校验类需要的参数
	 * @return de.schlichtherle.license.LicenseParam
	 * @author zifangsky
	 * @date 2018/4/20 10:56
	 * @since 1.0.0
	 */
	private LicenseParam initLicenseParam(LicenseVerifyParam param) {
		Preferences preferences = Preferences.userNodeForPackage(LicenseVerify.class);

		CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());

		KeyStoreParam publicStoreParam = new CustomKeyStoreParam(LicenseVerify.class
			, param.getPublicKeysStorePath()
			, param.getPublicAlias()
			, param.getStorePass()
			, null);

		return new DefaultLicenseParam(param.getSubject()
			, preferences
			, publicStoreParam
			, cipherParam);
	}


}
